package com.gomyb.admin.core.shiro;

import com.gomyb.admin.module.user.model.SysPermission;
import com.gomyb.admin.module.user.model.SysRole;
import com.gomyb.admin.module.user.model.SysUser;
import com.gomyb.admin.module.user.service.SysPermissionService;
import com.gomyb.admin.module.user.service.SysRoleService;
import com.gomyb.admin.module.user.service.SysUserService;
import com.gomyb.common.page.QueryFilter;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.List;

/**
 * @author <a href="mailto:hellohesir@gmail.com">Mr_He</a>
 */
public class MyShiroRealm extends AuthorizingRealm {

    @Autowired
    private SysUserService sysUserService;

    @Autowired
    private SysRoleService SysRoleService;

    @Autowired
    private SysPermissionService SysPermissionService;


    public static final String ADMIN_NAME = "admin";
    public static final String COMMON_NAME = "common";

    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
        Object userName = principals.getPrimaryPrincipal();
        if (null != userName) {
            if (userName.equals(ADMIN_NAME)) {
                authorizationInfo.addRole(ADMIN_NAME);

                List<SysRole> roles = SysRoleService.findAll();
                for (SysRole role : roles) {
                    authorizationInfo.addRole(role.getName());
                }
                List<SysPermission> permissions = SysPermissionService.findAll();
                for (SysPermission permission : permissions) {
                    authorizationInfo.addStringPermission(permission.getPermissionUrl());
                }
            } else {
                authorizationInfo.addRole(COMMON_NAME);

                QueryFilter filter = new QueryFilter();
                filter.eq("status",1);
                filter.eq("isDefault",1);
                List<SysPermission> defPermission = SysPermissionService.findAll(filter);
                for (SysPermission permission : defPermission) {
                    authorizationInfo.addStringPermission(permission.getPermissionUrl());
                }

                SysUser user = sysUserService.getByUsername(userName.toString());
                // 授权
                for (SysRole role : user.getRoleList()) {
                    authorizationInfo.addRole(role.getName());
                    for (SysPermission permission : role.getPermissionList()) {
                        authorizationInfo.addStringPermission(permission.getPermissionUrl());
                    }
                }
            }
        }
        return authorizationInfo;
    }

    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        //UsernamePasswordToken对象用来存放提交的登录信息
        UsernamePasswordToken token = (UsernamePasswordToken) authenticationToken;
        //实际项目中，这里可以根据实际情况做缓存，如果不做，Shiro自己也是有时间间隔机制，2分钟内不会重复执行该方法
        SysUser user = sysUserService.getByUsername(token.getUsername());
        //用户是否存在
        if (user == null) {
            throw new UnknownAccountException();
        }
        //是否激活
        if (user.getStatus().equals(0)) {
            throw new DisabledAccountException();
        }
        //若存在，将此用户存放到登录认证info中，无需自己做密码对比Shiro会为我们进行密码对比校验
        ByteSource credentialsSalt = ByteSource.Util.bytes(user.getSalt());
        return new SimpleAuthenticationInfo(
                user.getUsername(), //用户名
                user.getPassword(), //密码
                credentialsSalt,//salt
                getName()  //realm name
        );
    }

}

